package com.ys.service.storage.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.ys.config.MenuId;
import com.ys.dto.AddDto;
import com.ys.entity.storage.*;
import com.ys.entity.flow.YspModel;
import com.ys.entity.sys.TsUserChange;
import com.ys.entity.sys.YsCol;
import com.ys.entity.sys.YsMenu;
import com.ys.entity.sys.YsProcInst;
import com.ys.enume.flow.FlowEnum;
import com.ys.enume.flow.YsProcInstEnum;
import com.ys.enume.storage.TccStockSourceEnum;
import com.ys.mapper.storage.*;
import com.ys.mapper.hr.HrMapper;
import com.ys.service.business.TcwAccountDetailedForCompanyService;
import com.ys.service.storage.TccStockControlService;
import com.ys.service.storage.TccStockStoreService;
import com.ys.service.flow.YspTaskService;
import com.ys.service.sys.CommonApiService;
import com.ys.util.CheckUtil;
import com.ys.util.DateUtil;
import com.ys.util.shiro.ShiroUtils;
import com.ys.vo.Flow;
import com.ys.vo.R;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.*;

/**
 *
 */
@Service("tccStockStoreService")
public class TccStockStoreServiceImpl implements TccStockStoreService {
	@Autowired
	private TccStockStoreMapper tccStockStoreMapper;

	@Autowired
	private TccStockStoreItemMapper tccStockStoreItemMapper;

	@Autowired
	private TccStockControlRunningMapper tccStockControlRunningMapper;

	@Autowired
	private StorageMapper storageMapper;

	@Autowired
	private YspTaskService yspTaskService;

	@Autowired
	private CheckUtil checkUtil;

	@Autowired
	private HrMapper hrMapper;

	@Autowired
	private TccStockControlService tccStockControlService;

	@Autowired
	private CommonApiService<TccStockStore> commonApiService;

	@Autowired
	private TccStockSourceMapper tccStockSourceMapper;
	/*
	 * 新增
	 */
	@Override
	@Transactional(timeout=120,propagation= Propagation.REQUIRES_NEW)
	public R add(String bid, String remark, String detailArr,String vgsbm ) throws Exception {
		if (bid == null){
			return R.error("单号不允许为空!");
		}
		TccStockStore tccStockStore = new TccStockStore();
		tccStockStore.setBid(bid);
		tccStockStore.setRemark(remark);

		// 验证是否有详情数据
		JSONArray detailJA = JSON.parseArray(detailArr);
		if (detailJA == null || detailJA.size() == 0) {
			return R.error("详情数据不能为空");
		}

		for (int i = 0; i < detailJA.size(); i++) {
			JSONObject detailJO = detailJA.getJSONObject(i);
			if (detailJO.getInteger("num") == null){
				return R.error("出库数量不能为空!");
			}else if (detailJO.getInteger("num") == 0){
				return R.error("出库数量不能0!");
			}
		}

		String loginUserId = ShiroUtils.getUserId();
		TsUserChange tsUserChange = new TsUserChange().setUserId(loginUserId).setStatus(1).queryFirst();

		tccStockStore.setStatus(1);
		tccStockStore.setCreateChangeld(tsUserChange.getId());
		tccStockStore.setEffectStock(FlowEnum.EffectStock.NOT_EFFECT.value);
		tccStockStoreMapper.insert(tccStockStore);


		for (int i = 0; i < detailJA.size(); i++) {
			JSONObject detailJO = detailJA.getJSONObject(i);
			TccStockStoreItem tccStockStoreItem = JSON.parseObject(JSON.toJSONString(detailJO), TccStockStoreItem.class);
			tccStockStoreItem.setPbid(bid);
			tccStockStoreItem.setVgsbm(vgsbm);
			tccStockStoreItem.setCode((detailJO.getString("code")));
			tccStockStoreItem.setName((detailJO.getString("name")));
			tccStockStoreItem.setCodeMerge((detailJO.getString("codeMerge")));
			tccStockStoreItem.setIsParent(detailJO.getInteger("isParent"));
			tccStockStoreItem.setStatus(1);
			if(tccStockStoreItem.getNum()>0) {
				tccStockStoreItemMapper.insert(tccStockStoreItem);
			}else {
				return  R.error("出库数量小于0！");
			}
		}
		YsMenu ysMenu = new YsMenu().setId(MenuId.TCC_StockStore).queryFirst();
		if (ysMenu.getFlowModelId().longValue() != 0L) {
			YspModel yspModel = new YspModel().setId(ysMenu.getFlowModelId()).queryFirst();
			String codeModel = yspModel.getCode();
			String createUserId = ShiroUtils.getUserId();
			yspTaskService.init(codeModel, bid, createUserId);
		}
		return R.ok(AddDto.gotoEdit("/web/storage/tccStockStore/toEdit?bid=" + bid));
	}

	/**
	 * 修改
	 * @throws Exception
	 */
	@Override
	@Transactional(timeout=120,propagation= Propagation.REQUIRES_NEW)
	public R edit(String bid, String remark, String detailArr) throws Exception {
		if (bid == null){
			return R.error("单号不允许为空!");
		}
		TccStockStore tccStockStore = new TccStockStore().setBid(bid).queryFirst();
		if (tccStockStore == null){
			return R.error("库存入库单不存在!");
		}
		tccStockStore.setRemark(remark);

		// 验证是否有详情数据
		JSONArray detailJA = JSON.parseArray(detailArr);
		if (detailJA == null || detailJA.size() == 0) {
			return R.error("详情数据不能为空");
		}

		for (int i = 0; i < detailJA.size(); i++) {
			JSONObject detailJO = detailJA.getJSONObject(i);
			if (detailJO.getInteger("num") == null){
				return R.error("出库数量不能为空!");
			}else if (detailJO.getInteger("num") == 0){
				return R.error("出库数量不能0!");
			}
		}

		tccStockStoreMapper.update(tccStockStore);

		hrMapper.deleteTccStockStoreItemByBid(bid);

		for (int i = 0; i < detailJA.size(); i++) {
			JSONObject detailJO = detailJA.getJSONObject(i);
			TccStockStoreItem tccStockStoreItem = JSON.parseObject(JSON.toJSONString(detailJO), TccStockStoreItem.class);
			tccStockStoreItem.setPbid(bid);
			tccStockStoreItem.setCode((detailJO.getString("code")));
			tccStockStoreItem.setName((detailJO.getString("name")));
			tccStockStoreItem.setCodeMerge((detailJO.getString("codeMerge")));

			if(tccStockStoreItem.getNum()>0) {
				tccStockStoreItemMapper.insert(tccStockStoreItem);
			}else {
				return  R.error("出库数量不能小于0！");
			}
		}

		return R.ok(AddDto.gotoEdit("/web/storage/tccStockStore/toEdit?bid=" + bid));
	}



	@Override
	@Transactional(timeout=120,propagation= Propagation.REQUIRES_NEW)
	public R deleteTrue(Long id) throws Exception {
		if (id == null) {
			return R.error("ID不能为空");
		}
		TccStockStore entity = new TccStockStore().setId(id).queryFirst();
		if (entity.getEffectStock() == FlowEnum.EffectStock.EFFECTED.value) {
			return R.error("已生效数据无法删除");
		}
		// 验证是否制单人
		String loginUserId = ShiroUtils.getUserId();
		TsUserChange tsUserChange = new TsUserChange().setId(entity.getCreateChangeld()).queryFirst();

		if (!tsUserChange.getUserId().equals(loginUserId)) {
			return R.error("非制单人，无法删除");
		}

		// 删除主数据
		tccStockStoreMapper.deleteTrue(id);

		// 删除子数据
		List<TccStockStoreItem> listDetail = new TccStockStoreItem().setPbid(entity.getBid()).queryList();
		for(TccStockStoreItem detail : listDetail) {
			tccStockStoreItemMapper.deleteTrue(detail.getId());
		}

		yspTaskService.flowDelete(entity.getBid(), loginUserId);
		return R.ok();
	}

	/**
	 * 流转
	 */
	@Override
	@Transactional(timeout=120,propagation= Propagation.REQUIRES_NEW)
	public R flowPass(Long id, String loginUserId) throws Exception {
		TccStockStore entity = new TccStockStore().setId(id).queryFirst();
		if (entity == null) {
			return R.error("库存出库单不存在!");
		}

		String bid = entity.getBid();
		YsProcInst ysProcInst = new YsProcInst().setBid(bid).queryFirst();
		Flow f = yspTaskService.flowPass(bid, loginUserId);

		if (f.getCode() == Flow.Code.FAILED.value) {
			return R.error(f.getMsg());
		} else {
			// 若是制单流转，冻结库存
			if (ysProcInst.getStateFlow() == YsProcInstEnum.StateFlow.INIT.value) {
				List<TccStockStoreItem> itemList = new TccStockStoreItem().setPbid(bid).queryList();
				if(itemList == null || itemList.size()<=0){
					return R.error("该单据列表不存在,请核实后再操作!");
				}
//				//冻结
//				for(TccStockStoreItem item:itemList){
//					tccStockControlService.frozen(
//							item.getId(),
//							item.getNum(),
//							TccStockSourceEnum.Source.TCC_StockStore.value,
//							entity.getBid(),
//							item.getId()
//					);
//				}
			}
			if (f.getState() == Flow.State.FINISH.value) {
				R r = flowFinish(entity);
				if (r.getCode() == 1) {
					return R.error(r.getMsg());
				}
			}
		}


		return R.ok();
	}

	@Override
	@Transactional(timeout=120,propagation= Propagation.REQUIRES_NEW)
	public R flowRefuse(Long id, String reason, String loginUserId) throws Exception {
		TccStockStore entity = new TccStockStore().setId(id).queryFirst();
		if (entity == null) {
			return R.error("库存出库单不存在!");
		}
		String bid = entity.getBid();
		R r = yspTaskService.flowRefuse(bid, reason, ShiroUtils.getUserId());
		YsProcInst ysProcInst = new YsProcInst().setBid(bid).queryFirst();

		if (r.getCode() == R.Code.SUCCESS.value) {
			// 若退回到制单状态，则解冻库存
			if (ysProcInst.getStateFlow() == YsProcInstEnum.StateFlow.INIT.value) {
				List<TccStockStoreItem> itemList = new TccStockStoreItem().setPbid(bid).queryList();
				if(itemList == null || itemList.size()<=0){
					throw new IllegalArgumentException("该单据列表不存在,请核实后再操作!");
				}
				//解冻
				for(TccStockStoreItem item:itemList){
					tccStockControlService.thaw(
							item.getId(),
							item.getNum(),
							TccStockSourceEnum.Source.TCC_StockStore.value,
							entity.getBid(),
							item.getId()
					);
				}
			}
		}
		return r;
	}

	//流转驳回
	@Override
	@Transactional(timeout=120,propagation= Propagation.REQUIRES_NEW)
	public R flowInit(Long id, String reason,String loginUserId) throws Exception{
		TccStockStore entity = new TccStockStore().setId(id).queryFirst();
		if (entity == null) {
			return R.error("库存出库单不存在!");
		}
		String bid = entity.getBid();
		R r = yspTaskService.flowInit(bid, reason, ShiroUtils.getUserId());
		YsProcInst ysProcInst = new YsProcInst().setBid(bid).queryFirst();
		if (r.getCode() == R.Code.SUCCESS.value) {
			// 若退回到制单状态，则解冻库存
			if (ysProcInst.getStateFlow() == YsProcInstEnum.StateFlow.INIT.value) {
				List<TccStockStoreItem> itemList = new TccStockStoreItem().setPbid(bid).queryList();
				if(itemList == null || itemList.size()<=0){
					throw new IllegalArgumentException("该单据列表不存在,请核实后再操作!");
				}
				//解冻
				for(TccStockStoreItem item:itemList){
					tccStockControlService.thaw(
							item.getId(),
							item.getNum(),
							TccStockSourceEnum.Source.TCC_StockStore.value,
							entity.getBid(),
							item.getId()
					);
				}
			}
		}
		return r;
	}

	/**
	 * 流转结束
	 */
	public R flowFinish(TccStockStore entity) throws Exception {
		try {
			YsProcInst ysProcInst = new YsProcInst().setBid(entity.getBid()).queryFirst();
			if (ysProcInst.getStateFlow() != YsProcInstEnum.StateFlow.FINISH.value) {
				return R.error("流程状态有误");
			}
			Date theDate = new Date();
			entity.setEffectStock(FlowEnum.EffectStock.EFFECTED.value);
			entity.setUpdateTime(theDate);


			List<TccStockStoreItem> tccStockStoreItems = new TccStockStoreItem().setPbid(entity.getBid()).queryList();
			for (TccStockStoreItem tccStockStoreItem : tccStockStoreItems){
//				//解冻
//				tccStockControlService.thaw(
//						tccStockStoreItem.getId(),
//						tccStockStoreItem.getNum(),//数量
//						TccStockSourceEnum.Source.TCC_StockStore.value,
//						entity.getBid(),
//						entity.getId()
//				);
				//出库
				String remark = "库存入库单单号：" + entity.getBid();
				TccStockStore tccStockStore=new TccStockStore().setBid(tccStockStoreItem.getPbid());
				Integer sourceType = TccStockSourceEnum.Source.TCC_StockStore.value;
				Date drksj = new Date();
				Integer isParent =tccStockStoreItem.getIsParent();
				R res =tccStockControlService.inWithRunning(tccStockStoreItem.getPbid(),tccStockStoreItem.getChw(),tccStockStoreItem.getName(),tccStockStoreItem.getNum(),tccStockStoreItem.getCode(),tccStockStoreItem.getNum(),
						BigDecimal.ZERO,BigDecimal.ZERO,BigDecimal.ZERO,BigDecimal.ZERO,tccStockStoreItem.getVgsbm(),drksj,isParent,tccStockStore.getBid(),sourceType,remark,tccStockStoreItem.getCompanyVid(), null,tccStockStore.getId());
				if (res.getCode() != 0) {
					throw new RuntimeException(res.getMsg());
				}
				tccStockStoreItem.setStockControlId(Long.parseLong(res.get("data").toString()));

				tccStockStoreItemMapper.update(tccStockStoreItem);
			}
			tccStockStoreMapper.update(entity);
		}catch (Exception e){
			throw new RuntimeException(e.getMessage());
		}
		return R.ok();
	}
	//获取列表数据
	@Override
	@Transactional
	public Map<String,Object> getExtraParam( String bid) throws Exception{
		Map<String,Object> entity = new TccStockStore()

				.addLeftJoin("YS_ProcInst P ON P.Bid = A.Bid ")
				.addLeftJoin("TS_UserChange U ON U.Id = A.CreateChangeld ")
				.addField("U.UserId + '/' + U.UserName AS _ys_createUserName")//制单人
				.addField("CASE WHEN P.UpdateTime IS NULL AND A.EffectStock = 1 THEN FORMAT(A.UpdateTime, 'yyyy-MM-dd HH:mm:ss') ELSE FORMAT(P.UpdateTime, 'yyyy-MM-dd HH:mm:ss') END auditingTime")//审核时间
				.addLeftJoin("TCC_StockStoreItem B ON B.Pbid=A.Bid")
				.addLeftJoin("TB_CompanyInfo D ON D.Vid=B.CompanyVid")
				.addLeftJoin("TCC_Location TL ON TL.Chw=B.Chw")
				.addLeftJoin("THR_OperateCompanyApply TOC ON TOC.VGsBm=B.Vgsbm")

				.addLeftJoin("TCC_WarehouseArea TW ON TW.Ckq=TL.Ckq")
				.addLeftJoin("TCC_Warehouse TWh ON TWh.Cck=TW.Cck")
				.addLeftJoin("TB_Country TC ON TC.code = TWh.countryCode")
				.addField("TWh.Cck cck,TWh.Vck vck,TWh.CountryCode countryCode,TWh.City city,TC.name countryName")

				.addField("B.Code code,B.Name name,B.CodeMerge codeMerge,B.IsParent isParent,D.Vname companyVname,B.Num num," +
						"TL.Vhw vhw,TW.Vkq vkq,TWh.Vck gdepot,TOC.VGsJc vgsjc")
				.setBid(bid)
				.queryFirstMap();

		return entity;
	}


	//获取子列表数据
	@Override
	@Transactional
	public List<Map<String, Object>> getItemList( String bid) throws Exception{
		List<Map<String, Object>> itemList = new TccStockStoreItem()

				.addLeftJoin("TCC_StockStore B ON A.Pbid=B.Bid")
				.addLeftJoin("TB_CompanyInfo D ON D.Vid=A.CompanyVid")
				.addLeftJoin("TCC_Location TL ON TL.Chw=A.Chw")

				.addLeftJoin("TCC_WarehouseArea TW ON TW.Ckq=TL.Ckq")
				.addLeftJoin("TCC_Warehouse TWh ON TWh.Cck=TW.Cck")
				.addLeftJoin("TB_Country TC ON TC.code = TWh.countryCode")
				.addField("TWh.Cck cck,TWh.Vck vck,TWh.CountryCode countryCode,TWh.City city,TC.name countryName")
				.addField("FORMAT(A.UpdateTime, 'yyyy-MM-dd HH:mm:ss') AS drksj")//入库时间
				.addField("DATEDIFF(day, A.UpdateTime, getdate()) kcdays")//库存天数
//				.addLeftJoin("( SELECT bb.Id, bb.Code, bb.Name,bb.SubCodeMerge codeMerge FROM TP_ProductBasisComponent bb UNION ALL  SELECT cc.Id,cc.Code, cc.Name,cc.CodeMerge codeMerge FROM TP_ProductActive cc)dd ON" +
//						" dd.Code code,dd.Name name,dd.CodeMerge codeMerge")

				.addLeftJoin("THR_OperateCompanyApply TOC ON TOC.VGsBm=A.Vgsbm")
				.addField("A.Code code,A.Name name,A.CodeMerge codeMerge,A.IsParent isParent,D.Vname companyVname,A.Num num,A.Price price," +
						"TL.Vhw vhw,TW.Vkq vkq,TWh.Vck gdepot,TOC.VGsJc vgsjc")
				.setStatus(1)
				.setPbid(bid)
				.queryMap();
		return itemList;
	}
	@Override
	@Transactional
	public R toDelByItem(Long id) throws Exception {

		TccStockStoreItem tccStockStoreItem = new TccStockStoreItem();
		tccStockStoreItem.setId(id);
		tccStockStoreItem.setStatus(0);
		tccStockStoreItemMapper.update(tccStockStoreItem);
		return R.ok();
	}

}